<?php
class Model_Permissions extends Model{
	
 	protected static $_instance =  null;
 	static protected $_fields = array('view','edit','delete','publish','module');
	/**
     * @return Model_Permissions
     */
	static public function getInstance(){
        if(is_null(self::$_instance))	
           self::$_instance = new self('permissions');     
        return self::$_instance;   
    }
	/**
     * Get modules permissions for user
     * @param integer $userId
     * @param integer $groupId
     * @throws Exception
     * @return array
     */
    public function getPermissions($userId , $groupId){
    	
         if(empty($userId))
            throw new Exception('Need user id');
                     
         $cache = Application::dataCache();   
            
        /*
         * Check if cache exists
         */ 
    	if($cache && $data = $cache->load('user_permissions' . $userId))
    		return $data;
		
    	$data = array();	
    	/*
    	 * Load permissions for group
    	 */	
    	if($groupId){	
    		
    	 	$sql = $this->_db->select()
            				 ->from($this->table() , self::$_fields)
            				 ->where('`group_id` = '.intval($groupId));
            $groupRights = $this->_db->fetchAll($sql);
            
            if(!empty($groupRights))
            	$data =  Utils::rekey('module', $groupRights);				 	
    	}           
         /*
          * Load permissions for user
          */
         $sql = $this->_db	->select()
				            ->from($this->table() , self::$_fields)
				            ->where('`user_id` = '.intval($userId));

         $userRights = $this->_db->fetchAll($sql);
         
         /*
          * Replace group permissions by permissions redefined for concrete user
          */
         if(!empty($userRights))
             $data = array_merge($data , Utils::rekey('module', $userRights));

         /*
          * Cache info
          */    
         if($cache)
         	$cache->save($data , 'user_permissions' . $userId);

         return $data;	
    }
    
    /**
     * Get permissions for user group
     * Return permissions list indexed by module id
     * @return array
     */
    public function getGroupPermissions($groupId){
    	$data = array();
    	$cache = Application::dataCache();   
            
        /*
         * Check if cache exists
         */ 
    	if($cache && $data = $cache->load('group_permissions' . $groupId))
    		return $data;
    		
    	$sql = $this->_db	->select()
            				->from($this->table() , self::$_fields)
            				->where('`group_id` = '.intval($groupId));
        $data = $this->_db->fetchAll($sql);

        if(!empty($data))
            $data =  Utils::rekey('module', $data);		
    		
         /*
          * Cache info
          */    
         if($cache)
         	$cache->save($data , 'group_permissions' . $groupId);    
            
		return $data;      
    }
    /**
     * Update group permissions
     * @param integer $groupId
     * @param array $data - permissions like array(
     * 													array(
     * 														'module'=>'module',
     * 														'view'=>true,
     * 														'edit'=>false,
     * 														'delete'=>false,
     * 														'publish'=>false
     * 													), 
     * 													...
     * 												)
     * @return boolean
     */
    public function updateGroupPermissions($groupId , $data){

        $this->removeGroup($groupId);      	
    	foreach ($data as $values){
    			
    			/**
    			 * Check if all needed fields are present
    			 */
    			$diff = array_diff(self::$_fields, array_keys($values));
    			if(!empty($diff))
    				return false;
    			
    			try {
                    $obj = new Db_Object($this->_name);                    
			    	$obj->setValues(array(
						    				'module'=>$values['module'],
						    				'view'=>$values['view'],
							    			'edit'=>$values['edit'],
							    			'delete'=>$values['delete'],
							    			'publish'=>$values['publish'],
						    				'module'=>$values['module'],
						    				'group_id'=>$groupId,
    								  		'user_id'=>0
						    		));
			    	$obj->save();
    			}catch (Exception $e){
    				return false;
    			}
    	}
    	return  true;
    }
    /**
     * Remove group permissions
     * @param integer $groupId
     * @return boolean
     */
    public function removeGroup($groupId){
    	$select = $this->_db->select()
    						->from($this->table(), 'id')
    						->where('`user_id` = 0')
    						->where('`group_id` = ?', $groupId);
    	$groupIds = $this->_db->fetchCol($select);
    	
		$store = Db_Object_Store::getInstance();
		
        if(!empty($groupIds) && !$store->deleteObjects($this->_name, $groupIds))
            return false;
		
    	/**
		 * Invalidate Cache
    	 */
    	$cache = Application::dataCache(); 
    	
    	if($cache)
         	$cache->remove('group_permissions' . $groupId);
         	 
    	return  true;
    }
}